/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package xin.alum.aim.socks;

import io.netty.buffer.AbstractReferenceCountedByteBuf;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import xin.alum.aim.Aim;
import xin.alum.aim.constant.AimClose;
import xin.alum.aim.handler.BaseServerHandler;
import xin.alum.aim.model.Events;

/**
 * 处理消息
 */
@ChannelHandler.Sharable
public class SocksServerHandler extends BaseServerHandler<Object> {

    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) {
        ctx.executor().execute(() -> {
            if (msg instanceof xin.alum.aim.model.Aim.Packet) {
                xin.alum.aim.model.Aim.Packet m = (xin.alum.aim.model.Aim.Packet) msg;
                if (m.getData().is(xin.alum.aim.model.Aim.Login.class)) {
                    try {
                        xin.alum.aim.model.Aim.Login login = m.getData().unpack(xin.alum.aim.model.Aim.Login.class);
                        if (Aim.request.onHandShake(ctx.channel(), login.getToken())) {
                            Aim.request.onHandShaked(ctx.channel());
                        } else {
                            Aim.request.onClose(ctx.channel(), AimClose.HANDSHAKE);
                            super.onClose(ctx.channel(), AimClose.HANDSHAKE);
                        }
                    } catch (Exception e) {
                        logger.error(e);
                    }
                } else {
                    Events events = new Events();
                    events.setKey(m.getKey());
                    events.setTimestamp(m.getTimestamp());
                    events.setData(m.getData());
                    Aim.request.onRecive(ctx.channel(), events);
                }
            } else if (msg instanceof AbstractReferenceCountedByteBuf) {
                Aim.request.onByte(ctx.channel(), (ByteBuf) msg);
            } else if (msg instanceof String) {
                Aim.request.onText(ctx.channel(), (String) msg);
            } else {
                logger.error("{} 未知消息类型", ctx.channel());
            }
        });
    }
}
